const { Service } = require("egg");
const {
  createTempDir,
  downloadFile,
  transformVideo,
} = require("../utils/transformVideo");

class TopicLessonVideoService extends Service {
  constructor(ctx) {
    super(ctx);
    this.ctx = ctx;
    this.cosService = ctx.service.cos;
  }

  async list(lessonId) {
    return await this.ctx.model.TopicLessonVideo.findAll({
      where: {
        lessonId,
      },
      order: [["createdAt", "ASC"]],
      attributes: {
        exclude: ['originalVideoLink'],
      },
      raw: true,
    });
  }

  async get(id) {

    return await this.ctx.model.TopicLessonVideo.findByPk(id, {
      raw: true,
      attributes: ["*"],
    });
  }

  async create(data) {
    return await this.ctx.model.TopicLessonVideo.create(data);
  }

  async delete(id) {
    return await this.ctx.model.TopicLessonVideo.destroy({
      where: { id },
    });
  }

  async update(id, updateData) {
    const TopicInfo = await this.ctx.model.TopicLessonVideo.findOne({
      where: { id },
    });
    if (TopicInfo) {
      const updatedTopic = await this.ctx.model.TopicLessonVideo.update(
        updateData,
        {
          where: { id },
        }
      );
      return updatedTopic[0] ? updatedTopic[0] : null;
    }
    return null;
  }

  async updateStreaming(id) {
    this.ctx.logger.info("updateStreaming---start");

    const datas = await this.ctx.model.TopicLessonVideo.findOne({
      where: { id },
    });
    if (datas) {
      datas.transcodingStatus = 1;
      await datas.save();
    } else {
      this.ctx.logger.warn(`No record found with id: ${id}`);
    }
    const { originalVideoLink } = datas;

    this.ctx.logger.info("updateStreaming---TranscodingStatus");

    const { dir, cleanupHandle } = await createTempDir();

    try {
      const videoDir = await downloadFile(originalVideoLink, dir);
      this.ctx.logger.info("updateStreaming---videoDir", videoDir);
      const { outputDir, infos }  = await transformVideo(videoDir, dir);
      this.ctx.logger.info("updateStreaming---outputDir", outputDir);


      infos.poster = await this.cosService.baseUpload(infos.poster, `assets/topic-lesson-video/poster/${id}.jpg`);

      try {
        const result = await this.cosService.uploadDirectory(
          outputDir,
          `assets/topic-lesson-videos/${id}/`
        );

        this.ctx.logger.info("updateStreaming---result", result);

        result.find((item) => {
          if (item.fileName.includes("m3u8")) {
            this.ctx.model.TopicLessonVideo.update(
              {
                streamingVideoLink: item.url,
                infos,
                transcodingStatus: 2,
              },
              {
                where: { id },
              }
            );
            cleanupHandle();
          }
        });
      } catch (error) {
        this.ctx.logger.error("updateStreaming---error", error);
        cleanupHandle();
      }
      return id;
    } catch (error) {
      this.ctx.logger.error("updateStreaming---error", error);
      cleanupHandle();
    }
  }

  async findVideosWithOriginalButNoStreamingLink() {
    const { Op } = this.app.Sequelize;

    const data = await this.ctx.model.TopicLessonVideo.findAll({
      where: {
        originalVideoLink: { [Op.ne]: null },
        streamingVideoLink: null,
      },
      order: [["updatedAt", "DESC"]],
      raw: true,
    });
    return data;

  }
}

module.exports = TopicLessonVideoService;
